package com.zzyl.nursing.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import java.util.Objects;

import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.dto.ElderFamilyDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.ICheckInService;
import org.springframework.transaction.annotation.Transactional;

/**
 * checkInService业务层处理
 *
 * @author ruoyi
 * @date 2025-07-25
 */
@Service
@Slf4j
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BedMapper bedMapper;


    /**
     * 申请入住
     *
     * @param checkInApplyDto
     */
    @Transactional
    @Override
    public void apply(CheckInApplyDto checkInApplyDto) {
        //判断老人是否入住
        //查询老人 通过身份证号查询
        LambdaQueryWrapper<Elder> elderLambdaQueryWrapper = new LambdaQueryWrapper<Elder>();
        elderLambdaQueryWrapper.eq(Elder::getIdCardNo, checkInApplyDto.getCheckInElderDto().getIdCardNo())
                .eq(Elder::getStatus, 1);
        Elder elder = elderMapper.selectOne(elderLambdaQueryWrapper);

        if (ObjectUtils.isNotEmpty(elder)) {

            throw new BaseException("老人已入住");
        }

        //更新床位的状态
        Bed bed = bedMapper.selectBedById(checkInApplyDto.getCheckInConfigDto().getBedId());
        bed.setBedStatus(1);
        bedMapper.updateById(bed);

        //保存老人数据
        elder = insertOrUpdate(bed, checkInApplyDto.getCheckInElderDto());

        //生成合同编号
        String contractNo = "HT" + CodeGenerator.generateContractNumber();

        //新增签约办理
        insertContract(contractNo, elder, checkInApplyDto);

        //新增入住信息
        CheckIn checkIn = insertCheckIn(elder, checkInApplyDto);

        //新增入住配置信息
        insertCheckInConfig(checkIn.getId(), checkInApplyDto);

    }

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;


    /**
     * 新增入住配置
     *
     * @Param checkInApplyDto
     */
    private void insertCheckInConfig(Integer checkInId, CheckInApplyDto checkInApplyDto) {

        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInApplyDto.getCheckInConfigDto(), checkInConfig);


        checkInConfig.setCheckInId(checkInId);

        //tNursingLevelId查询
        checkInConfigMapper.insert(checkInConfig);
    }

    /**
     * 新增入住信息
     *
     * @param elder
     * @param checkInApplyDto
     */
    private CheckIn insertCheckIn(Elder elder, CheckInApplyDto checkInApplyDto) {
        CheckIn checkIn = new CheckIn();
        checkIn.setElderId(elder.getId());
        checkIn.setElderName(elder.getName());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setNursingLevelName(checkInApplyDto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setRemark(JSON.toJSONString(checkInApplyDto.getElderFamilyDtoList()));
        checkIn.setStatus(0);
        checkIn.setCreateTime(new Date());
        checkInMapper.insert(checkIn);
        return checkIn;
    }

    @Autowired
    private ContractMapper contractMapper;

    /**
     * 新增合同
     *
     * @param contractNO
     * @param elder
     * @param checkInApplyDto
     */


    private void insertContract(String contractNO, Elder elder, CheckInApplyDto checkInApplyDto) {

        Contract contract = new Contract();


        BeanUtils.copyProperties(checkInApplyDto.getCheckInContractDto(), contract);
        //属性拷贝
        contract.setContractNumber(contractNO);
        contract.setSignDate(LocalDateTime.now());
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        //状态 开始时间 结束时间
        //签约时间小于等于当前时间，合同生效
        LocalDateTime checkInStartTime = checkInApplyDto.getCheckInConfigDto().getStartDate();
        LocalDateTime checkInEndTime = checkInApplyDto.getCheckInConfigDto().getEndDate();

        Integer status = checkInStartTime.isAfter(LocalDateTime.now()) ? 1 : 0;
        contract.setStatus(status);
        contract.setStartDate(checkInStartTime);
        contract.setEndDate(checkInEndTime);

        contractMapper.insert(contract);

    }


    private Elder insertOrUpdate(Bed bed, CheckInElderDto checkInElderDto) {

        Elder elder = new Elder();

        BeanUtils.copyProperties(checkInElderDto, elder);

        elder.setBedNumber((bed.getId()).toString());
        elder.setStatus(1);
        elder.setCreateTime(new Date());

        LambdaQueryWrapper<Elder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Elder::getIdCardNo, checkInElderDto.getIdCardNo())
                .eq(Elder::getStatus, 0);
        Elder elderDb = elderMapper.selectOne(lambdaQueryWrapper);


        if (ObjectUtils.isNotEmpty(elderDb)) {
            elderMapper.updateById(elder);
        } else {

            elderMapper.insert(elder);
        }

        return elder;
    }


    /**
     * 查询checkIn
     *
     * @param id checkIn主键
     * @return checkIn
     */
    @Override
    public CheckIn selectCheckInById(Integer id) {
        return checkInMapper.selectById(id);
    }

    /**
     * 查询checkIn列表
     *
     * @param checkIn checkIn
     * @return checkIn
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增checkIn
     *
     * @param checkIn checkIn
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        checkIn.setCreateTime(DateUtils.getNowDate());
        return checkInMapper.insert(checkIn);
    }

    /**
     * 修改checkIn
     *
     * @param checkIn checkIn
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        checkIn.setUpdateTime(DateUtils.getNowDate());
        return checkInMapper.updateById(checkIn);
    }

    /**
     * 批量删除checkIn
     *
     * @param ids 需要删除的checkIn主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Integer[] ids) {
        return checkInMapper.deleteByIds(Arrays.asList(ids));
    }

    /**
     * 删除checkIn信息
     *
     * @param id checkIn主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Integer id) {
        return checkInMapper.deleteById(id);
    }

    @Override
    public CheckInDetailVo detail(Long id) {
        //查询四张表数据
        CheckIn checkIn = checkInMapper.selectById(id);

        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(Wrappers.<CheckInConfig>lambdaQuery()
                .eq(CheckInConfig::getCheckInId, id)
        );

        Contract contract = contractMapper.selectOne(Wrappers.<Contract>lambdaQuery()
                .eq(Contract::getElderId, checkIn.getElderId())
                .eq(Contract::getStatus, 0)
                .last("limit 1")
                //排序
                .orderByDesc(Contract::getCreateTime)
        );
        log.info("contract的值为{}",contract);

        Elder elder = elderMapper.selectById(checkIn.getElderId());

        //vo转换
        CheckInDetailVo vo = new CheckInDetailVo();




        CheckInElderVo checkInElderVo=new CheckInElderVo();
        BeanUtils.copyProperties(elder,checkInElderVo);

        vo.setCheckInElderVo(checkInElderVo);

        String remark = checkIn.getRemark();
        if(!Objects.isNull(remark)){
            List<ElderFamilyVo> elderFamilyVoList= JSONUtil.toList(remark,ElderFamilyVo.class);

            vo.setElderFamilyVoList(elderFamilyVoList);
        }


        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();

        BeanUtils.copyProperties(checkIn,checkInConfig);
        BeanUtils.copyProperties(checkIn,checkInConfigVo);
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());



        vo.setCheckInConfigVo(checkInConfigVo);
        vo.setContract(contract);


        return vo;

    }

    @Scheduled(cron = "0 0 0 * * ?" )
    public void taskCheck(){


        List<CheckIn> checkInList = checkInMapper.selectList(new LambdaQueryWrapper<>());
        checkInList.forEach((item)->{
            LocalDateTime currentTime= LocalDateTime.now();

            if (item.getEndDate().isAfter(currentTime)){

                log.warn("{}该用户合同已过期",item.getIdCardNo());

            }
            if (item.getStartDate().isBefore(currentTime)){

                log.warn("{}该用户合同已过期",item.getIdCardNo());

            }

        });


    }










}
